<?php
/**
 * $Id: router.php 21 2009-06-10 02:24:31Z eyou80 $
 */

/**
 * 路由分发类
 *
 * @package Router
 */
class Tinyask_Router
{
	/**
	 * 当前路由名称
	 *
	 * @var string
	 */
	public static $current;

	/**
	 * 路由分发配置信息
	 *
	 * @var array
	 */
	private static $_table = array();

	/**
	 * 解析路径为路由
	 *
	 * @param string $pathInfo
	 * @return mixed
	 */
	public static function match($pathInfo)
	{
		foreach(self::$_table as $key => $route) {
			$matches = array();
			if(preg_match($route['regx'], $pathInfo, $matches)) {
				self::$current = $key;

				if(!empty($route['params'])) {
					unset($matches[0]);
					$params = array_combine($route['params'], $matches);
					foreach ($params as $name => $value) {
						Tinyask_Request::setParam($name, $value);
					}
				}
				return $route;
			}
		}
		return false;
	}

	/**
	 * 设置路由器配置信息
	 *
	 * @param array $routes
	 */
	public static function setRoutes($routes)
	{
		if(isset($routes[0])) {
			self::$_table = $routes[0];
		} else {
			/** 载入路由解析支持 */
			require_once 'tinyask/router/parser.php';

			/** 解析路由配置 */
			$parser = new Tinyask_Router_Parser($routes);
			self::$_table = $parser->parse();
		}
	}

	/**
	 * 获取指定路由信息
	 *
	 * @param string $routeName
	 * @return mixed
	 */
	public static function get($key)
	{
		return isset(self::$_table[$key]) ? self::$_table[$key] : null;
	}

	/**
	 * 路由分发函数
	 *
	 * @throws Tinyask_Exception
	 */
	public static function route()
	{
		$pathInfo = Tinyask_Request::getPathInfo();

		foreach (self::$_table as $key => $route) {
			$matches = array();
			if(preg_match($route['regx'], $pathInfo, $matches)) {
				self::$current = $key;

				try {
					$params = null;

					if(!empty($route['params'])) {
						unset($matches[0]);
						$params = array_combine($route['params'], $matches);
						foreach ($params as $name => $value) {
							Tinyask_Request::setParam($name, $value);
						}
					}

					$app = Tinyask_App::app($route['app']);

					if(isset($route['ac'])) {
						$app->{$route['ac']}();
					}
					return;
				} catch(Exception $e) {
					if($e->getCode() == 404) {
						Tinyask_App::destory($route['app']);
						continue;
					}

					throw $e;
				}
			}
		}

		throw new Tinyask_Exception("Path '{$pathInfo}' not found", 404);
	}

	/**
	 * 根据路由信息合成路径
	 *
	 * @param string $key 路由配置名称
	 * @param array $value
	 * @param string $prefix
	 * @return string
	 */
	public static function url($key, array $value = null, $prefix = null)
	{
		$route = self::$_table[$key];

		$rows = array();
		foreach ($route['params'] as $row) {
			$rows[$row] = isset($value[$row]) ? $value[$row] : '{' . $row . '}';
		}
		return Tinyask_Common::url(vsprintf($route['format'], $rows), $prefix);
	}
}
